package com.bkgy.controller.zincpot.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bkgy.commom.model.QueryDTO;
import com.bkgy.controller.zincpot.dto.ZincPotHisPageDTO;
import com.bkgy.controller.zincpot.entity.ZincPidHisEntity;
import com.bkgy.controller.zincpot.entity.ZincPotEntity;
import com.bkgy.controller.zincpot.entity.ZincPotHisEntity;
import com.bkgy.controller.zincpot.mapper.ZincPidHisMapper;
import com.bkgy.controller.zincpot.mapper.ZincPotHisMapper;
import com.bkgy.controller.zincpot.mapper.ZincPotMapper;
import com.bkgy.controller.zincpot.service.ZincPotService;
import com.bkgy.controller.zincpot.vo.ZincPotHisPageVO;
import com.bkgy.sys.common.entity.ResultData;
import com.bkgy.util.ExcelUtilsPOI;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;


@Service
@Transactional
public class ZincPotServiceImpl extends ServiceImpl<ZincPotMapper, ZincPotEntity> implements ZincPotService {

    @Autowired
    private ZincPotMapper zincPotMapper;

    @Autowired
    private ZincPidHisMapper zincPidHisMapper;

    @Autowired
    private ZincPotHisMapper zincPotHisMapper;

    @Resource
    private HttpServletResponse response;

    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;

    @Override
    public List<ZincPotEntity> getP8Calc() {
        try {
            LambdaQueryWrapper<ZincPotEntity> wrapper = new LambdaQueryWrapper<>();
//            List<Integer> iStateAs = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 7, 8, 9, 10));
//            wrapper.in(ZincPotEntity::getIStateA, iStateAs).or(w3 -> w3
//                            .in(ZincPotEntity::getIStateA, 6, 5).eq(ZincPotEntity::getIStateC, 1));
            //TODO
            List<Integer> iStateAs = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20));
            wrapper.in(ZincPotEntity::getIStateA, iStateAs);
            wrapper.orderByDesc(ZincPotEntity::getIndocno).last(" FETCH FIRST 10 ROWS ONLY");
            return zincPotMapper.selectList(wrapper);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<ZincPidHisEntity> getWindTurbine() {
        try {
            LambdaQueryWrapper<ZincPidHisEntity> wrapper = new LambdaQueryWrapper<>();
            wrapper.orderByDesc(ZincPidHisEntity::getIndocno).last(" FETCH FIRST 10 ROWS ONLY");
            return zincPidHisMapper.selectList(wrapper);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public ResultData<List<ZincPotHisPageVO>> getZincPotHisPage(QueryDTO<ZincPotHisPageDTO> queryDTO) {
        try {
            LambdaQueryWrapper<ZincPotHisEntity> wrapper = new LambdaQueryWrapper<>();
            wrapper.orderByDesc(ZincPotHisEntity::getToc);
            ZincPotHisPageDTO dto = queryDTO.getDto();
            // 处理起始时间和终止时间的不同为空情况
            if (!isEmpty(dto.getStartToc()) && !isEmpty(dto.getEndToc())) {
                // 两个时间都不为空，使用between
                wrapper.between(ZincPotHisEntity::getToc, dto.getStartToc(), dto.getEndToc());
            } else if (!isEmpty(dto.getStartToc()) && isEmpty(dto.getEndToc())) {
                // 起始时间不为空，使用大于等于
                wrapper.ge(ZincPotHisEntity::getToc, dto.getStartToc());
            } else if (!isEmpty(dto.getEndToc()) && isEmpty(dto.getStartToc())) {
                // 终止时间不为空，使用小于等于
                wrapper.le(ZincPotHisEntity::getToc, dto.getEndToc());
            }
            // 出口卷号
            if (!isEmpty(dto.getExtid())) {
                wrapper.like(ZincPotHisEntity::getExtid, dto.getExtid());
            }
            Page<ZincPotHisEntity> page = new Page<>(queryDTO.getPage().getPageIndex(), queryDTO.getPage().getPageSize());
            Page<ZincPotHisEntity> result = zincPotHisMapper.selectPage(page, wrapper);
            List<ZincPotHisPageVO> list = result.getRecords().stream().map(item -> {
                ZincPotHisPageVO vo = new ZincPotHisPageVO();
                BeanUtils.copyProperties(item, vo);
                return vo;
            }).collect(Collectors.toList());
            return ResultData.ResultDataSuccess(list, (int) result.getTotal());
        } catch (Exception e) {
            return ResultData.ResultDataFaultSelf("获取数据失败，错误信息为" + e.getMessage(), null);
        }
    }

    private boolean isEmpty(String string) {
        return string == null || string.isEmpty();
    }

    @Override
    public void exportExcel(ZincPotHisPageDTO queryDTO) {

        Integer pageCount;
        Integer pageSize = 5000;
        StringBuilder fileNameBuilder = new StringBuilder("镀锌1870锌锅分档记录");

        LambdaQueryWrapper<ZincPotHisEntity> wrapper = new LambdaQueryWrapper<>();
        // 出口卷号
        if (!isEmpty(queryDTO.getExtid())) {
            wrapper.like(ZincPotHisEntity::getExtid, queryDTO.getExtid());
            fileNameBuilder.append("-extid-").append(queryDTO.getExtid());
        }
        if (!isEmpty(queryDTO.getStartToc()) && !isEmpty(queryDTO.getEndToc())) {
            wrapper.between(ZincPotHisEntity::getToc, queryDTO.getStartToc(), queryDTO.getEndToc());
            fileNameBuilder.append("-begin-").append(queryDTO.getStartToc().replaceAll("\\s+", "")).append("-end-").append(queryDTO.getEndToc().replaceAll("\\s+", ""));
        } else if (!isEmpty(queryDTO.getStartToc()) && isEmpty(queryDTO.getEndToc())) {
            // 起始时间不为空，使用大于等于
            wrapper.ge(ZincPotHisEntity::getToc, queryDTO.getStartToc());
            fileNameBuilder.append("-begin-").append(queryDTO.getStartToc().replaceAll("\\s+", ""));
        } else if (!isEmpty(queryDTO.getEndToc()) && isEmpty(queryDTO.getStartToc())) {
            // 终止时间不为空，使用小于等于
            wrapper.le(ZincPotHisEntity::getToc, queryDTO.getEndToc());
            fileNameBuilder.append("-end-").append(queryDTO.getEndToc().replaceAll("\\s+", ""));
        }
        long total = zincPotHisMapper.selectCount(wrapper);
        if (total == 0) {
            throw new RuntimeException("当前无数据可导出。");                              // 无数据直接返回
        }
        pageCount = (int) ((total + pageSize - 1) / pageSize);

        try {
            int colNum = 10;

            // 使用SXSSFWorkbook提高大数据量导出性能
            SXSSFWorkbook workbook = new SXSSFWorkbook(100); // 保持100行在内存中
            Sheet sheet = workbook.createSheet("镀锌1870锌锅分档记录");

            // 创建合并居中的表头
            Row headerRow = sheet.createRow(0);
            headerRow.setHeightInPoints(30); // 设置行高

            // 创建表头单元格并合并
            org.apache.poi.ss.usermodel.Cell headerCell = headerRow.createCell(0);
            headerCell.setCellValue("镀锌1870锌锅分档记录");

            // 合并单元格
            sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(0, 0, 0, colNum));

            // 设置表头样式
            org.apache.poi.ss.usermodel.CellStyle headerStyle = workbook.createCellStyle();
            org.apache.poi.ss.usermodel.Font font = workbook.createFont();
            font.setBold(true);
            font.setFontHeightInPoints((short) 16);
            headerStyle.setFont(font);
            headerStyle.setAlignment(org.apache.poi.ss.usermodel.HorizontalAlignment.CENTER);
            headerStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
            headerCell.setCellStyle(headerStyle);

            // 创建列标题行
            Row titleRow = sheet.createRow(1);
            titleRow.createCell(0).setCellValue("序号");
            titleRow.createCell(1).setCellValue("镀锌出口卷号");
            titleRow.createCell(2).setCellValue("入口卷号");
            titleRow.createCell(3).setCellValue("钢种");
            titleRow.createCell(4).setCellValue("出口厚度");
            titleRow.createCell(5).setCellValue("入口厚度");
            titleRow.createCell(6).setCellValue("快冷段带温实际-平均值");
            titleRow.createCell(7).setCellValue("快冷段带温设定-平均值");
            titleRow.createCell(8).setCellValue("GI锌锅温度-平均值");
            titleRow.createCell(9).setCellValue("GA锌锅温度-平均值");
            titleRow.createCell(10).setCellValue("TOC");

            // 设置标题行样式
            org.apache.poi.ss.usermodel.CellStyle titleStyle = workbook.createCellStyle();
            org.apache.poi.ss.usermodel.Font titleFont = workbook.createFont();
            titleFont.setBold(true);
            titleStyle.setFont(titleFont);
            titleStyle.setAlignment(org.apache.poi.ss.usermodel.HorizontalAlignment.CENTER);
            for (int i = 0; i < colNum; i++) { // 根据列数调整
                titleRow.getCell(i).setCellStyle(titleStyle);
            }

            // 设置列宽
            for (int i = 0; i < colNum; i++) {
                sheet.setColumnWidth(i, 20 * 256);   // 序号列
            }

            // 分页查询数据并写入Excel
            wrapper.orderByDesc(ZincPotHisEntity::getToc);
            wrapper.select(ZincPotHisEntity::getIndocno,
                    ZincPotHisEntity::getExtid,
                    ZincPotHisEntity::getEntid,
                    ZincPotHisEntity::getSteelgrade,
                    ZincPotHisEntity::getOutMatThk,
                    ZincPotHisEntity::getInMatThk,
                    ZincPotHisEntity::getCglRcsStripTempActAvg,
                    ZincPotHisEntity::getCglRcsStripTempSetAvg,
                    ZincPotHisEntity::getCglGiZnpotTempAvg,
                    ZincPotHisEntity::getCglGaZnpotTempAvg,
                    ZincPotHisEntity::getToc);

            // 创建线程池
            ExecutorService executorService = Executors.newCachedThreadPool();

            // 当前写入Excel的行号和序号
            AtomicInteger currentRow = new AtomicInteger(2); // 数据从第三行开始
            AtomicInteger index = new AtomicInteger(1);

            // 创建CountDownLatch用于等待所有查询任务完成
            CountDownLatch queryLatch = new CountDownLatch(pageCount);
            List<ZincPotHisEntity> allData = new ArrayList<>();

            // 提交任务
            for (int i = 1; i <= pageCount; i++) {
                final int pageNum = i;
                executorService.submit(() -> {
                    try {
                        Page<ZincPotHisEntity> page = new Page<>(pageNum, pageSize);
                        Page<ZincPotHisEntity> zincPotHisEntityPage = zincPotHisMapper.selectPage(page, wrapper);
                        List<ZincPotHisEntity> pageList = zincPotHisEntityPage.getRecords();
                        allData.addAll(pageList);
                    } catch (Exception e) {
                        // 处理异常
                        throw new RuntimeException(e);
                    } finally {
                        queryLatch.countDown();
                    }
                });
            }

            boolean isCompleted = queryLatch.await(45, TimeUnit.SECONDS);
            if (!isCompleted) {
                executorService.shutdownNow(); // 超时中断所有任务
                throw new RuntimeException("查询超时，导出失败");
            }
            executorService.shutdown(); // 正常关闭线程池

            allData.sort(Comparator.comparing(ZincPotHisEntity::getToc).reversed());
            // 按排序后的顺序写入Excel
            for (ZincPotHisEntity entity : allData) {
                Row dataRow = sheet.createRow(currentRow.getAndIncrement());
                dataRow.createCell(0).setCellValue(index.getAndIncrement());
                dataRow.createCell(1).setCellValue(entity.getExtid() != null ? entity.getExtid() : "");
                dataRow.createCell(2).setCellValue(entity.getEntid() != null ? entity.getEntid() : "");
                dataRow.createCell(3).setCellValue(entity.getSteelgrade() != null ? entity.getSteelgrade() : "");
                dataRow.createCell(4).setCellValue(entity.getOutMatThk() != null ? entity.getOutMatThk().toString() : "");
                dataRow.createCell(5).setCellValue(entity.getInMatThk() != null ? entity.getInMatThk().toString() : "");
                dataRow.createCell(6).setCellValue(entity.getCglRcsStripTempActAvg() != null ? entity.getCglRcsStripTempActAvg().toString() : "");
                dataRow.createCell(7).setCellValue(entity.getCglRcsStripTempSetAvg() != null ? entity.getCglRcsStripTempSetAvg().toString() : "");
                dataRow.createCell(8).setCellValue(entity.getCglGiZnpotTempAvg() != null ? entity.getCglGiZnpotTempAvg().toString() : "");
                dataRow.createCell(9).setCellValue(entity.getCglGaZnpotTempAvg() != null ? entity.getCglGaZnpotTempAvg().toString() : "");
                dataRow.createCell(10).setCellValue(entity.getToc() != null ? entity.getToc() : "");
            }

//            Map<String, Object> map = new HashMap<>();
//            map.put("data", allData);            // 与模板中{{data}}对应
//            File tpl = ResourceUtils.getFile("classpath:exceltemplate\\镀锌1870锌锅分档记录.xlsx");
//            TemplateExportParams params = new TemplateExportParams(tpl.getPath(), false);
//            params.setDictHandler(new PlanExcelHandlerImpl()); // 若有字典转换
//            Workbook workbook1 = ExcelExportUtil.exportExcel(params, map);
            ExcelUtilsPOI.exportExcel(fileNameBuilder.toString(), response, workbook);

//            // 清理临时文件
            workbook.dispose();

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("导出Excel失败，错误信息为" + e.getMessage());
        }
    }


//    @Override
//    public void exportExcel(ZincPotHisPageDTO queryDTO) {
//        // 构建文件名
//        StringBuilder fileNameBuilder = new StringBuilder("镀锌1870锌锅分档记录");
//
//        // 构建查询条件
//        LambdaQueryWrapper<ZincPotHisEntity> wrapper = new LambdaQueryWrapper<>();
//        // 出口卷号
//        if (!isEmpty(queryDTO.getExtid())) {
//            wrapper.like(ZincPotHisEntity::getExtid, queryDTO.getExtid());
//            fileNameBuilder.append("-extid-").append(queryDTO.getExtid());
//        }
//        if (!isEmpty(queryDTO.getStartToc()) && !isEmpty(queryDTO.getEndToc())) {
//            wrapper.between(ZincPotHisEntity::getToc, queryDTO.getStartToc(), queryDTO.getEndToc());
//            fileNameBuilder.append("-begin-").append(queryDTO.getStartToc().replaceAll("\\s+", "")).append("-end-").append(queryDTO.getEndToc().replaceAll("\\s+", ""));
//        } else if (!isEmpty(queryDTO.getStartToc()) && isEmpty(queryDTO.getEndToc())) {
//            // 起始时间不为空，使用大于等于
//            wrapper.ge(ZincPotHisEntity::getToc, queryDTO.getStartToc());
//            fileNameBuilder.append("-begin-").append(queryDTO.getStartToc().replaceAll("\\s+", ""));
//        } else if (!isEmpty(queryDTO.getEndToc()) && isEmpty(queryDTO.getStartToc())) {
//            // 终止时间不为空，使用小于等于
//            wrapper.le(ZincPotHisEntity::getToc, queryDTO.getEndToc());
//            fileNameBuilder.append("-end-").append(queryDTO.getEndToc().replaceAll("\\s+", ""));
//        }
//
//        // 检查是否有数据
//        long total = zincPotHisMapper.selectCount(wrapper);
//        if (total == 0) {
//            throw new RuntimeException("当前无数据可导出。");
//        }
//
//        try {
//            // 设置响应头
//            String fileName = URLEncoder.encode(fileNameBuilder + ".xlsx", "UTF-8");
//            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
//            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
//
//            // ExcelWriter构建
//            OutputStream out = response.getOutputStream();
//            ExcelWriter excelWriter = EasyExcel.write(out, ZincPotHisExcelVO.class)
//                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
//                    .build();
//
//            // 创建工作表
//            WriteSheet writeSheet = EasyExcel.writerSheet("锌锅分档记录")
//                    .head(ZincPotHisExcelVO.class) // 显式指定表头
//                    .build();
//
//            // 分页查询参数
//            int pageSize = 5000;
//            int pageNum = 1;
//            boolean hasMoreData = true;
//
//            // 获取批量操作的SqlSession
//            SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
//            ZincPotHisMapper batchMapper = session.getMapper(ZincPotHisMapper.class);
//
//            try {
//                while (hasMoreData) {
//                    // 分页查询
//                    Page<ZincPotHisEntity> page = new Page<>(pageNum, pageSize);
//                    Page<ZincPotHisEntity> resultPage = batchMapper.selectPage(page, wrapper);
//
//                    List<ZincPotHisEntity> records = resultPage.getRecords();
//                    if (records.isEmpty()) {
//                        hasMoreData = false;
//                        break;
//                    }
//
//                    // 转换为VO
//                    List<ZincPotHisExcelVO> voList = convertToVO(records);
//
//                    // 3.1.4版本兼容的写入方式
//                    excelWriter.write(voList, writeSheet);
//
//                    // 清理内存
//                    records.clear();
//                    voList.clear();
//
//                    pageNum++;
//                }
//            } finally {
//                // 关闭资源（3.1.4版本需要确保流正确关闭）
//                if (excelWriter != null) {
//                    excelWriter.finish();
//                }
//                session.commit();
//                session.close();
//                out.flush();
//                out.close();
//            }
//
//        } catch (Exception e) {
//            log.error("导出Excel失败", e);
//            throw new RuntimeException("导出Excel失败，错误信息为：" + e.getMessage());
//        }
//    }
//
//    // 实体转换工具方法
//    private List<ZincPotHisExcelVO> convertToVO(List<ZincPotHisEntity> entities) {
//        List<ZincPotHisExcelVO> voList = new ArrayList<>(entities.size());
//        for (ZincPotHisEntity entity : entities) {
//            ZincPotHisExcelVO vo = new ZincPotHisExcelVO();
//            // 属性复制，可使用BeanUtils等工具类
//            vo.setExtid(entity.getExtid());
//            vo.setEntid(entity.getEntid());
//            vo.setSteelgrade(entity.getSteelgrade());
//            vo.setOutMatThk(entity.getOutMatThk());
//            vo.setInMatThk(entity.getInMatThk());
//            vo.setCglRcsStripTempActAvg(entity.getCglRcsStripTempActAvg());
//            vo.setCglRcsStripTempSetAvg(entity.getCglRcsStripTempSetAvg());
//            vo.setCglGiZnpotTempAvg(entity.getCglGiZnpotTempAvg());
//            vo.setCglGaZnpotTempAvg(entity.getCglGaZnpotTempAvg());
//            vo.setToc(entity.getToc());
//            voList.add(vo);
//        }
//        return voList;
//    }


}